﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Windows.Forms;
using ExtensionMethods;
using PpSmsSender;

namespace RatatoskBgServer
{
    public partial class Form1 : Form
    {
        private PpSmsSender.DbSmsSender smsSender;
        private readonly ManualResetEvent _shutdownEvent = new ManualResetEvent(false);
        private readonly ManualResetEvent _startedEvent = new ManualResetEvent(false);
        private volatile bool shutdownRequested;
        private volatile bool hasStopped = false;
        private DateTime lastReport;

        public Form1()
        {
            InitializeComponent();
        }

        private static Type GetPlugin(string dllName, string interfaceName)
        {
            Type phoneNumberType = null;
            string phonedll = dllName;
            if (phonedll != "")
            {
                var binFolder = EnvironmentUtils.BinFolder();
                var a = Assembly.LoadFrom(binFolder + @"\" + phonedll);

                foreach (Type t in a.GetTypes().Where(t => t.GetInterface(interfaceName) != null))
                {
                    try
                    {
                        phoneNumberType = t;
                        break;
                    }
                    catch
                    {
                    }
                }
            }
            return phoneNumberType;
        }


        private void ReportCallback(string msg)
        {
            if (lastReport.Date != DateTime.Now.Date)
                Trace.WriteLine("=========== " + DateTime.Now.ToString("yyyy-MM-dd") + " =======================");
            lastReport = DateTime.Now;
            Trace.Write(lastReport.ToString("HH:mm:ss ") + msg);
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            Type phoneNumberType = GetPlugin("" + ConfigurationManager.AppSettings["phoneNumberPlugIn"], "IPhoneNumber") ?? typeof (PhoneNumber);


            List<string> phonelist = new List<string>();

            string conf = ConfigurationManager.AppSettings["rootDirPrefix"] + ConfigurationManager.AppSettings["modemConfigFile"];
            Thread thread =
                new Thread(() =>
                               {
                                   try
                                   {
                                       using (this.smsSender = new DbSmsSender(phoneNumberType, conf, this.ReportCallback))
                                       {
                                           this._startedEvent.Set();
                                           this._shutdownEvent.WaitOne(Timeout.Infinite);
                                       }
                                   }
                                   catch (Exception ex)
                                   {
                                       Trace.WriteLine(ex.Message);
                                   }
                                   this.hasStopped = true;
                                   this.smsSender = null;
                               });
            thread.Start();
            Trace.WriteLine("Waiting for startup....");
            var waitResult = this._startedEvent.WaitOne(TimeSpan.FromSeconds(60));


            if (waitResult == false)
            {
                Trace.WriteLine("\r\n\r\nFailed to start");
                Console.Error.WriteLine("Timed out in startup. " + (phonelist.Count == 0 ? "No modems connected" : ""));
                this.shutdownRequested = true;
                this._shutdownEvent.Set();
                Thread.Sleep(3000);
                Environment.Exit(1);
            }
            Trace.WriteLine("\r\n\r\nStartup done.\r\nEnter command");

        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            Trace.WriteLine("Window Closing");
            shutdownRequested = true;
            _shutdownEvent.Set();

            while (hasStopped == false || shutdownRequested == false)
                Thread.Sleep(1000);
            Environment.Exit(0);

        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            Trace.WriteLine("Window Closed");
        }
    }
}
